package dbexp.connection;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import dbexp.model.Column;
import dbexp.model.DbObject;
import dbexp.model.Function;
import dbexp.model.Index;
import dbexp.model.Package;
import dbexp.model.PackageBody;
import dbexp.model.Procedure;
import dbexp.model.Role;
import dbexp.model.Schema;
import dbexp.model.Sequence;
import dbexp.model.Synonym;
import dbexp.model.Table;
import dbexp.model.TableData;
import dbexp.model.Trigger;
import dbexp.model.User;
import dbexp.model.View;
import dbexp.model.db.DbUser;

/**
 * @author Michał Skrzyński
 * @email michal_skrzynski@o2.pl
 */
public class DbMetaData {
	/**
	 * @throws DbAccessException
	 * @throws DbStateException
	 * @throws PoolManagerException
	 * @throws DbQueryException
	 * @throws SQLException
	 */
	public static DbUser createConnection(DbUser u) throws PoolManagerException,
			DbStateException, DbAccessException, SQLException {
		DbUser newUser = DbConnection.getInstance().getNewUser(u);
		return newUser;
	}

	public static Connection getConnection(DbUser u) throws DbAccessException,
			DbStateException, PoolManagerException {
		return DbConnection.getIFor(u).getConnection();
	}

	public static List<Column> getColumnsFromQuery(DbUser u, String query)
			throws SQLException, PoolManagerException, DbAccessException,
			DbStateException {
		return DbConnection.getIFor(u).getColumnsFromQuery(query);
	}
	public static String getDDL(DbUser u, DbObject o) throws PoolManagerException, DbAccessException, DbStateException, SQLException{
		return DbConnection.getIFor(u).getDDL(o);
	}
	public static TableData getData(DbUser u, String query)
			throws SQLException, PoolManagerException, DbAccessException,
			DbStateException {
		return DbConnection.getIFor(u).getData(query);
	}

	public static long getCount(DbUser u, String name) throws SQLException,
			PoolManagerException, DbAccessException, DbStateException {
		return DbConnection.getIFor(u).getCount(name);
	}

	/**
	 * @return status operacji EXIST=23, ERROR=9,OK=0
	 */
	public static int operateObject(DbUser u, DbObject o, int operate)
			throws SQLException, PoolManagerException, DbAccessException,
			DbStateException, DbQueryException {
		return DbConnection.getIFor(u).operateObject(o, operate);
	}

	/***************************************************************/
	public static boolean destroyConnection(DbUser u) {
		return DbConnection.getIFor(u).destroyConnection(u);
	}

	public static View getView(DbUser u, String n, String s)
			throws PoolManagerException, DbAccessException, DbStateException,
			DbQueryException, SQLException {
		return DbConnection.getIFor(u).getView(n, s);
	}

	public static List<DbObject> getTablespaces(DbUser u)
			throws DbAccessException, DbStateException {
		return DbConnection.getIFor(u).getTablespaces();
	}

	public static List<DbObject> getProfile(DbUser u) throws DbAccessException,
			DbStateException {
		return DbConnection.getIFor(u).getProfile();
	}

	// ***************************************************************************************
	public static List<Table> getTables(DbUser u, String s, String n)
			throws PoolManagerException, DbAccessException, DbStateException,
			DbQueryException, SQLException {
		return DbConnection.getIFor(u).getTables(s, n);
	}

	/**********************************************************************************************************************************/
	public static Sequence getSequence(DbUser u, String n, String s)
			throws PoolManagerException, DbAccessException, DbStateException,
			DbQueryException, SQLException {
		return DbConnection.getIFor(u).getSequence(n, s);
	}

	public static Synonym getSynonym(DbUser u, String n, String s)
			throws PoolManagerException, DbAccessException, DbStateException,
			DbQueryException, SQLException {
		return DbConnection.getIFor(u).getSynonym(n, s);
	}

	public static Function getFunction(DbUser u, String n, String s)
			throws PoolManagerException, DbAccessException, DbStateException,
			DbQueryException, SQLException {
		return Function.instantOf(DbConnection.getIFor(u).getSource(
				new Function(n, s)));
	}

	public static Index getIndex(DbUser u, String n, String s)
			throws PoolManagerException, DbAccessException, DbStateException,
			DbQueryException, SQLException {
		return DbConnection.getIFor(u).getIndex(n, s);
	}

	public static User getUser(DbUser u, String n) throws PoolManagerException,
			DbAccessException, DbStateException, DbQueryException, SQLException {
		return DbConnection.getIFor(u).getUser(n);
	}

	public static Trigger getTrigger(DbUser u, String n, String s)
			throws PoolManagerException, DbAccessException, DbStateException,
			DbQueryException, SQLException {
		return DbConnection.getIFor(u).getTrigger(n, s);
	}

	public static Table getTable(DbUser u, String n, String s)
			throws PoolManagerException, DbAccessException, DbStateException,
			DbQueryException, SQLException {
		return DbConnection.getIFor(u).getTable(n, s);
	}

	public static List<DbObject> getRoles(DbUser u) throws PoolManagerException,
			DbAccessException, DbStateException, DbQueryException, SQLException {
		return DbConnection.getIFor(u).getRoles(new Role());
	}

	public static List<DbObject> getSystemPrivs(DbUser u)
			throws PoolManagerException, DbAccessException, DbStateException,
			DbQueryException, SQLException {
		return DbConnection.getIFor(u).getSystemPrivs(new Role());
	}

	public static Procedure getProcedure(DbUser u, String n, String s)
			throws PoolManagerException, DbAccessException, DbStateException,
			DbQueryException, SQLException {
		return Procedure.instantOf(DbConnection.getIFor(u).getSource(
				new Procedure(n, s)));
	}

	public static PackageBody getPackageBody(DbUser u, String n, String s)
			throws PoolManagerException, DbAccessException, DbStateException,
			DbQueryException, SQLException {
		return PackageBody.instantOf(DbConnection.getIFor(u).getSource(
				new PackageBody(n, s)));
	}

	public static Package getPackage(DbUser u, String n, String s)
			throws PoolManagerException, DbAccessException, DbStateException,
			DbQueryException, SQLException {
		return Package.instantOf(DbConnection.getIFor(u).getSource(
				new Package(n, s)));
	}

	/**********************************************************************************************************************************/
	public static DbObject getSource(DbUser u, DbObject o)
			throws PoolManagerException, DbAccessException, DbStateException,
			DbQueryException, SQLException {
		return DbConnection.getIFor(u).getSource(o);
	}

	/**********************************************************************************************************************************/
	public static List<Schema> getAllSchemas(DbUser u)
			throws PoolManagerException, DbAccessException, DbStateException,
			DbQueryException, SQLException {
		return DbConnection.getIFor(u).getSchemas(null);
	}

	public static TableData getAllSchemas(DbUser u, String pattern)
			throws PoolManagerException, DbAccessException, DbStateException,
			DbQueryException, SQLException {
		String where = "";
		if (pattern != null) {
			where = " WHERE USERNAME LIKE '" + pattern + "%'";
		}
		return DbConnection.getIFor(u).getData(
				"SELECT USERNAME FROM ALL_USERS" + where +" ORDER BY USERNAME");
	}

	public static List<DbObject> getObjects(DbUser u, DbObject o)
			throws PoolManagerException, DbAccessException, DbStateException,
			DbQueryException, SQLException {
		return DbConnection.getIFor(u).getObjects(o);
	}

	public static DbObject getObject(DbUser u, DbObject o)
			throws PoolManagerException, DbAccessException, DbStateException,
			DbQueryException, SQLException {
		return DbConnection.getIFor(u).getObject(o);
	}

	public static List<DbObject> getSecurityObjects(DbUser u, DbObject o)
			throws PoolManagerException, DbAccessException, DbStateException,
			DbQueryException, SQLException {
		List<DbObject> vec = new ArrayList<DbObject>();
		if (o.isUser()) {
			vec = DbConnection.getIFor(u).getUsers(o);
		}
		return vec;
	}
}
